#!/usr/bin/perl

package FinanceUtils;

use strict;
use warnings;

use Finance::Quote;
use Finance::QuoteHist;
use Finance::TA;
use DBI;
use Data::Dumper;
use GD::Graph::ohlc;
use GD::Graph::mixed;
use GD::Graph::lines;
use List::Util qw(min max);

use Exporter;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);

$VERSION     = 1.00;
@ISA         = qw(Exporter);
@EXPORT      = (qw(&getIndicator &generatePriceImage &generateLineImage &updateStop)); 
@EXPORT_OK   = ();

sub updateStop {
    my $prevStop = shift;
    my $stopDist = shift;
    my $price    = shift;
    my $type     = shift;
    $prevStop = $price+$stopDist if $type eq "short" and not defined $prevStop;
    $prevStop = $price-$stopDist if $type eq "long" and not defined $prevStop;
    my $newStop = $prevStop;
    $newStop = $price+$stopDist if $type eq "short" and $price+$stopDist<$prevStop;
    $newStop = $price-$stopDist if $type eq "long" and $price-$stopDist>$prevStop;
    return $newStop;
}

sub getIndicator {
    my $indicators = shift;
    for(keys %$indicators){
        my $type = shift $indicators->{$_};
        my $splice = shift $indicators->{$_};
        my $opts = $indicators->{$_};
        print "Getting indicator $type, values @$splice with options @$opts\n";
        $indicators->{$_} = [];
        push $indicators->{$_}, ( &{\&{$type}}(@$opts) )[@$splice];
    }
    return $indicators;
}

sub generateLineImage {
    my $name = shift;
    my $data = [ shift ];
    push @$data, shift @_ while @_;
    my $graph = GD::Graph::lines->new(8000, 200);
    $graph->set ( x_label => "Date",
                  title   => "$name",
                  skip_undef => 1,
                  transparent => 0
                ) or die $graph->error;
    my $gp = $graph->plot($data) || die $graph->error;
    open(my $ifh, ">", "$name.png") || die "Can't open file $!\n";
    print $ifh $gp->png;
    close($ifh);
}

sub generatePriceImage {
    my $prices = shift;
    my $name = shift;
    my @ohlcDataset=();
    for my $index (1..$#{$prices->{date}}){
        push @ohlcDataset, [ $prices->{open}->[$index], $prices->{high}->[$index],
                             $prices->{low}->[$index], $prices->{close}->[$index] ];
    }
    my $data = [ $prices->{date}, \@ohlcDataset ];
    my @types = qw(ohlc);
    while (@_){
        push @$data, shift @_;
        push @types, qw(lines);
    }
    my $maxp = max(@{$prices->{high}});
    my $minp = min(@{$prices->{low}});
    my $graph = GD::Graph::mixed->new(8000, 800);
    $graph->set( x_label           => "Date",
                 y_label           => "$prices->{name}",
                 y_max_value       => 1.1*$maxp,
                 y_min_value       => 0.9*$minp,
                 title             => "$name",
                 skip_undef        => 1,
                 types             => [@types],
                 transparent       => 0
                 ) or die $graph->error;
    my $gd = $graph->plot($data) || die $graph->error;
    open(my $ifh, ">", "$name.png") || die "Can't open file $!\n";
    print $ifh $gd->png;
    close($ifh);
}


return 1;

